package edu.northwestern.cbits.purple_robot_manager.probes.builtin; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Enumeration; import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.text.format.Formatter; import edu.northwestern.cbits.purple_robot_manager.R; import edu.northwestern.cbits.purple_robot_manager.activities.settings.FlexibleListPreference; import edu.northwestern.cbits.purple_robot_manager.logging.LogManager; import edu.northwestern.cbits.purple_robot_manager.probes.Probe; public class NetworkProbe extends Probe { private static final String HOSTNAME = "HOSTNAME"; private static final String IP_ADDRESS = "IP_ADDRESS"; private static final String IFACE_NAME = "INTERFACE_NAME"; private static final String IFACE_DISPLAY_NAME = "INTERFACE_DISPLAY"; private static final boolean DEFAULT_ENABLED = true; private static final String ENABLED = "config_probe_network_enabled"; private static final String FREQUENCY = "config_probe_network_frequency"; private long _lastCheck = 0; @Override public String getPreferenceKey() { return "built_in_network"; } @Override public String name(Context context) { return "edu.northwestern.cbits.purple_robot_manager.probes.builtin.NetworkProbe"; } @Override public String title(Context context) { return context.getString(R.string.title_network_probe); } @Override public String probeCategory(Context context) { return context.getResources().getString(R.string.probe_device_info_category); } @Override public void enable(Context context) { SharedPreferences prefs = Probe.getPreferences(context); Editor e = prefs.edit(); e.putBoolean(NetworkProbe.ENABLED, true); e.commit(); } @Override public void disable(Context context) { SharedPreferences prefs = Probe.getPreferences(context); Editor e = prefs.edit(); e.putBoolean(NetworkProbe.ENABLED, false); e.commit(); } @Override public boolean isEnabled(final Context context) { SharedPreferences prefs = Probe.getPreferences(context); if (super.isEnabled(context)) { final long now = System.currentTimeMillis(); if (prefs.getBoolean(NetworkProbe.ENABLED, NetworkProbe.DEFAULT_ENABLED)) { synchronized (this) { long freq = Long.parseLong(prefs.getString(NetworkProbe.FREQUENCY, Probe.DEFAULT_FREQUENCY)); if (now - this._lastCheck > freq) { final NetworkProbe me = this; Runnable r = new Runnable() { @Override @SuppressWarnings("deprecation") public void run() { Bundle bundle = new Bundle(); bundle.putString("PROBE", me.name(context)); bundle.putLong("TIMESTAMP", System.currentTimeMillis() / 1000); WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); if (wifiInfo != null) { int ip = wifiInfo.getIpAddress(); String ipString = Formatter.formatIpAddress(ip); bundle.putString(NetworkProbe.IP_ADDRESS, ipString); try { NetworkInterface iface = NetworkInterface.getByInetAddress(InetAddress.getByName(ipString)); bundle.putString(NetworkProbe.IFACE_NAME, iface.getName()); bundle.putString(NetworkProbe.IFACE_DISPLAY_NAME, iface.getDisplayName()); bundle.putString(NetworkProbe.HOSTNAME, InetAddress.getByName(ipString).getHostName()); } catch (UnknownHostException | NullPointerException e) { bundle.putString(NetworkProbe.HOSTNAME, ipString); } catch (SocketException e) { e.printStackTrace(); } } else { try { Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); NetworkInterface iface = null; while (ifaces.hasMoreElements() && (iface = ifaces.nextElement()) != null && bundle.containsKey(NetworkProbe.IP_ADDRESS) == false) { if (iface.getName().equals("lo") == false) { Enumeration<InetAddress> ips = iface.getInetAddresses(); InetAddress ipAddr = null; while (ips.hasMoreElements() && (ipAddr = ips.nextElement()) != null) { bundle.putString(NetworkProbe.IP_ADDRESS, ipAddr.getHostAddress()); bundle.putString(NetworkProbe.HOSTNAME, ipAddr.getHostName()); bundle.putString(NetworkProbe.IFACE_NAME, iface.getName()); bundle.putString(NetworkProbe.IFACE_DISPLAY_NAME, iface.getDisplayName()); } } } } catch (SocketException e) { LogManager.getInstance(context).logException(e); } } if (bundle.containsKey(NetworkProbe.IP_ADDRESS) == false) { bundle.putString(NetworkProbe.IP_ADDRESS, "127.0.0.1"); bundle.putString(NetworkProbe.HOSTNAME, "localhost"); try { NetworkInterface iface = NetworkInterface.getByInetAddress(InetAddress.getByName("127.0.0.1")); bundle.putString(NetworkProbe.IFACE_NAME, iface.getName()); bundle.putString(NetworkProbe.IFACE_DISPLAY_NAME, iface.getDisplayName()); } catch (SocketException | UnknownHostException e) { LogManager.getInstance(context).logException(e); } } me.transmitData(context, bundle); me._lastCheck = now; } }; Thread t = new Thread(r); t.start(); } } return true; } } return false; } @Override public String summarizeValue(Context context, Bundle bundle) { String ipAddress = bundle.getString(NetworkProbe.IP_ADDRESS); return String.format(context.getResources().getString(R.string.summary_network_probe), ipAddress); } @Override public Map<String, Object> configuration(Context context) { Map<String, Object> map = super.configuration(context); SharedPreferences prefs = Probe.getPreferences(context); try { long freq = Long.parseLong(prefs.getString(NetworkProbe.FREQUENCY, Probe.DEFAULT_FREQUENCY)); map.put(Probe.PROBE_FREQUENCY, freq); } catch (NumberFormatException e) { LogManager.getInstance(context).logException(e); } return map; } @Override public void updateFromMap(Context context, Map<String, Object> params) { super.updateFromMap(context, params); if (params.containsKey(Probe.PROBE_FREQUENCY)) { Object frequency = params.get(Probe.PROBE_FREQUENCY); if ((frequency instanceof Double) == false) frequency = Double.valueOf(frequency.toString()).longValue(); else frequency = ((Double) frequency).longValue(); SharedPreferences prefs = Probe.getPreferences(context); Editor e = prefs.edit(); e.putString(NetworkProbe.FREQUENCY, frequency.toString()); e.commit(); } } @Override public String summary(Context context) { return context.getString(R.string.summary_network_probe_desc); } @Override @SuppressWarnings("deprecation") public PreferenceScreen preferenceScreen(Context context, PreferenceManager manager) { PreferenceScreen screen = super.preferenceScreen(context, manager); screen.setTitle(this.title(context)); screen.setSummary(R.string.summary_network_probe_desc); CheckBoxPreference enabled = new CheckBoxPreference(context); enabled.setTitle(R.string.title_enable_probe); enabled.setKey(NetworkProbe.ENABLED); enabled.setDefaultValue(NetworkProbe.DEFAULT_ENABLED); screen.addPreference(enabled); FlexibleListPreference duration = new FlexibleListPreference(context); duration.setKey(NetworkProbe.FREQUENCY); duration.setEntryValues(R.array.probe_satellite_frequency_values); duration.setEntries(R.array.probe_satellite_frequency_labels); duration.setTitle(R.string.probe_frequency_label); duration.setDefaultValue(Probe.DEFAULT_FREQUENCY); screen.addPreference(duration); return screen; } @Override public JSONObject fetchSettings(Context context) { JSONObject settings = super.fetchSettings(context); try { JSONObject frequency = new JSONObject(); frequency.put(Probe.PROBE_TYPE, Probe.PROBE_TYPE_LONG); JSONArray values = new JSONArray(); String[] options = context.getResources().getStringArray(R.array.probe_satellite_frequency_values); for (String option : options) { values.put(Long.parseLong(option)); } frequency.put(Probe.PROBE_VALUES, values); settings.put(Probe.PROBE_FREQUENCY, frequency); } catch (JSONException e) { LogManager.getInstance(context).logException(e); } return settings; } public String assetPath(Context context) { return "network-probe.html"; } }